/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ads.list;

/**
 *
 * @author framet
 */
public class SimpleListImpl implements SimpleListI {

    private Node head = null; // Listenkopf

    public SimpleListImpl() {
        head = new Node();
    }

    @Override
    public void addFirst(Object o) {
// neuen Knoten hinter head einfügen
        Node n = new Node(o, head.getNext());
        head.setNext(n);
    }

    @Override
    public void addLast(Object o) {
        Node l = head;
// letzten Knoten ermitteln
        while (l.getNext() != null) {
            l = l.getNext();
        }
        Node n = new Node(o, null);
// neuen Knoten anfügen
        l.setNext(n);
    }

    @Override
    public Object getFirst() throws ListEmptyException {
        if (isEmpty()) {
            throw new ListEmptyException();
        }
// erstes Element ist Nachfolger von head
        return head.getNext().getElement();
    }

    @Override
    public Object getLast() throws ListEmptyException {
        if (isEmpty()) {
            throw new ListEmptyException();
        }
        Node l = head;
// letzten Knoten ermitteln
        while (l.getNext() != null) {
            l = l.getNext();
        }
        return l.getElement();
    }

    @Override
    public Object removeFirst() throws ListEmptyException {
        if (isEmpty()) {
            throw new ListEmptyException();
        }
        Object o = head.getNext().getElement();
// Verweis von head aktualisieren
        head.setNext(head.getNext().getNext());
        return o;
    }

    @Override
    public Object removeLast() throws ListEmptyException {
        if (isEmpty()) {
            throw new ListEmptyException();
        }
        Node l = head;
// vorletzten Knoten ermitteln
        while (l.getNext().getNext() != null) {
            l = l.getNext();
        }
        Object o = l.getNext().getElement();
// Verweis auf Nachfolger löschen
        l.setNext(null);
        return o;
    }

    public int size() {
        int s = 0;
        Node n = head;
// Knoten zählen
        while (n.getNext() != null) {


            s++;
            n = n.getNext();
        }
        return s;
    }

    public boolean isEmpty() {
        return head.getNext() == null;
    }

    @Override
    public Object getNth(int index) throws ListEmptyException {
        if (isEmpty()) {
            throw new ListEmptyException();
        }
        Node l = head;
// letzten Knoten ermitteln
        int counter = 0;
        while (l.getNext() != null) {
            l = l.getNext();
            if (counter == index) {
                break;
            }
            counter++;
        }
        return l.getElement();
    }

    @Override
    public void addNth(Object obj, int index) {
        Node l = head;
// letzten Knoten ermitteln
        int counter = 0;
        while (l.getNext() != null) {
            if (counter == index) {
                break;
            }
            l = l.getNext();
            counter++;
        }
        Node ll = l.getNext();
        Node n = new Node(obj, ll);
        l.setNext(n);
    }

    private static class Node {

        Object element; // Element
        Node next; // Verweis auf Nachfolger
// Konstruktoren

        public Node(Object o, Node n) {
            element = o;
            next = n;
        }

        public Node() {
            element = null;
            next = null;
        }
// Element neu belegen

        public void setElement(Object o) {
            element = o;
        }
// Zugriff auf Element

        public Object getElement() {
            return element;
        }
// Nachfolger setzen

        public void setNext(Node n) {
            next = n;
        }

// Zugriff auf Nachfolger
        public Node getNext() {
            return next;
        }
    }
}
